package com.cloudfun.campusshare.util;

import com.google.common.collect.Lists;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.chrono.ChronoLocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * Created by linyangping on 2019/11/16.
 * 日期格式化
 */
public final class DateUtil {

    public final static String Format_Year_To_Day = "yyyy-MM-dd";
    public final static String Format_Year_To_Second = "yyyy-MM-dd HH:mm:ss";
    public final static DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(Format_Year_To_Day);
    public final static DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(Format_Year_To_Second);
    public final static DateTimeFormatter DATE_TIME_FORMATTER_NO_SEP = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    // date类型转换为String类型
    // formatType格式为yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
    // data Date类型的时间
    public static String dateToString(Date data, String formatType) {
        return new SimpleDateFormat(formatType).format(data);
    }

    public static String localDateToString(LocalDateTime localDateTime) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(Format_Year_To_Second);
        return localDateTime.format(dateTimeFormatter);
    }

    public static String customTransfer(ChronoLocalDate date,String pattern){
        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
        return date.format(df);
    }

    public static String computeBetweenLocalDate(LocalDateTime oldDate, LocalDateTime newDate) {
        Duration between = Duration.between(oldDate, newDate);
        StringBuffer sb = new StringBuffer();
        long min = between.toMinutes();
        long day = min / 1440;
        long hour = min % 1440 / 60;
        long minute = min % 60;
        return sb.append(day).append("天").append(hour).append("时").append(minute).append("分").toString();
    }

    public static void main(String[] args) {
        System.out.println(localDateToString(LocalDateTime.now()));
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(Format_Year_To_Second);
        LocalDateTime parse = LocalDateTime.parse("2020-05-10 15:23:00", dateTimeFormatter);
        System.out.println(computeBetweenLocalDate(parse, LocalDateTime.now()));
    }

    // long类型转换为String类型
    // currentTime要转换的long类型的时间
    // formatType要转换的string类型的时间格式
    public static String longToString(long currentTime, String formatType) {
        Date date = longToDate(currentTime, formatType); // long类型转成Date类型
        String strTime = dateToString(date, formatType); // date类型转成String
        return strTime;
    }

    // string类型转换为date类型
    // strTime要转换的string类型的时间，formatType要转换的格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日
    // HH时mm分ss秒，
    // strTime的时间格式必须要与formatType的时间格式相同
    public static Date stringToDate(String strTime, String formatType) {
        SimpleDateFormat formatter = new SimpleDateFormat(formatType);
        Date date = null;
        try {
            date = formatter.parse(strTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    // long转换为Date类型
    // currentTime要转换的long类型的时间
    // formatType要转换的时间格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
    public static Date longToDate(long currentTime, String formatType) {
        Date dateOld = new Date(currentTime); // 根据long类型的毫秒数生命一个date类型的时间
        String sDateTime = dateToString(dateOld, formatType); // 把date类型的时间转换为string
        Date date = stringToDate(sDateTime, formatType); // 把String类型转换为Date类型
        return date;
    }

    // string类型转换为long类型
    // strTime要转换的String类型的时间
    // formatType时间格式
    // strTime的时间格式和formatType的时间格式必须相同
    public static long stringToLong(String strTime, String formatType) {
        Date date = stringToDate(strTime, formatType); // String类型转成date类型
        if (date == null) {
            return 0;
        } else {
            long currentTime = dateToLong(date); // date类型转成long类型
            return currentTime;
        }
    }

    // date类型转换为long类型
    // date要转换的date类型的时间
    public static long dateToLong(Date date) {
        return date.getTime();
    }

    /**
     * 根据日期得到年(后两位)
     *
     * @param date 日期
     */
    public static String getYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        String year = String.valueOf(cal.get(Calendar.YEAR));
        return year.substring(year.length() - 2);
    }

    /**
     * 获取日期的月份（自动补零）
     *
     * @param date 日期
     * @return 返回月数
     */
    public static String getMoth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return String.format("%02d", cal.get(Calendar.MONTH) + 1);
    }

    /**
     * 获取日期的日期（自动补零）
     *
     * @param date 日期
     * @return 返回月数
     */
    public static String getDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return String.format("%02d", cal.get(Calendar.DATE) + 1);
    }

    /**
     * 比较两个时间戳的日期是否相同
     *
     * @param stamp1
     * @param stamp2
     * @return
     */
    public static boolean dateEquals(long stamp1, long stamp2) {
        Date date1 = longToDate(stamp1, Format_Year_To_Second);
        Date date2 = longToDate(stamp2, Format_Year_To_Second);
        return getDate(date1).equals(getDate(date2));
    }

    /**
     * 判断两个时间是否相差指定分钟
     *
     * @param _time1 时间戳1
     * @param _time2 时间戳2
     * @param minute 指定分钟
     * @return 超过指定分钟:false;未超过:true
     */
    public static boolean isTwoTimeDeltaMinute(long _time1, long _time2, int minute) {
        long deltaSecond = Math.abs(_time1 - _time2);
        long deltaMinute = deltaSecond / (1000 * 60);
        int curMinute = new Long(deltaMinute).intValue();
        return curMinute < minute;
    }

    /**
     * 获取最近天数的时间点列表
     *
     * @param day
     * @return
     */
    public static List<Long> getLastDayPoint(int day) {
        List<Long> result = new ArrayList<>();

        long current = System.currentTimeMillis();
        result.add(current);
        // 获取今日凌晨时间戳
        long time = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
        result.add(time);
        for (int i = 1; i < day; ++i) {
            time = time - (1000 * 3600 * 24);
            result.add(time);
        }
        return Lists.reverse(result);
    }

    /**
     * 获取最近天数的时间点列表
     *
     * @param start
     * @param end
     * @return
     */
    public static List<Long> getDayPointBetween(Long start, Long end) {
        List<Long> result = new ArrayList<>();

        long current = start;
        result.add(current);
        // 获取今日凌晨时间戳
        long time = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
        while (time < end) {
            time = time + (1000 * 3600 * 24);
            result.add(time);
        }
        return result;
    }

    /**
     * 获取今天至今的时间点（每小时）
     *
     * @return
     */
    public static List<Long> getTodayHourPoint() {
        long current = System.currentTimeMillis();
        // 获取今日凌晨时间戳
        long time = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
        List<Long> result = new LinkedList<>();
        int num = 24;
        while ((num--) > 0) {
            result.add(time);
            time = time + (1000 * 3600);
        }
        result.add(current);
        return result;
    }

    /**
     * 获取昨日时间点（每小时）
     *
     * @return
     */
    public static List<Long> getYestdayHourPoint() {
        long current = System.currentTimeMillis();
        // 获取今日凌晨时间戳
        long today = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
        long yesterday = today - (1000 * 3600 * 24);
        List<Long> result = new LinkedList<>();
        int num = 25;
        while ((num--) > 0) {
            result.add(yesterday);
            yesterday = yesterday + (1000 * 3600);
        }
//        result.add(yesterday - 1000);
//        result.add(yesterday - 1000);
        return result;
    }

    public static long toEpochMilli(LocalDateTime localDateTime) {
        return localDateTime.toInstant(OffsetDateTime.now().getOffset()).toEpochMilli();
    }

}
